
<html><HEAD>
<LINK REL=STYLESHEET HREF="default.css" TYPE="text/css">
<TITLE>
Client- and component-demarcated transactions</TITLE>
</HEAD>
<BODY>

<!-- Header -->
<p class="ancestor" align="right"><A HREF="apptechp152.htm">Previous</A>&nbsp;&nbsp;<A HREF="apptechp154.htm" >Next</A>
<!-- End Header -->
<A NAME="BABJIAFE"></A><h1>Client- and component-demarcated transactions</h1>
<A NAME="TI4826"></A><p>Client applications and <ABBR title = "e a server" >EAServer</ABBR> components
marked as OTS style or Bean Managed can create, control, and obtain
information about <ABBR title = "e a server" >EAServer</ABBR> transactions
using functions of the CORBACurrent context service object. The CORBACurrent
object provides most of the methods defined for the CORBA Current
interface. </p>
<A NAME="TI4827"></A><h4>Two-phase commit</h4>
<A NAME="TI4828"></A><p>Components in a client- or component-demarcated transaction
must be running on a server that is using the OTS/XA transaction
coordinator. This transaction coordinator supports the two-phase
commit protocol, which uses detailed records from all participants
to protect against system failures. In the prepare phase, the transaction
coordinator obtains a guarantee from every participant in the transaction
that it can be committed and writes a prepare record to the log. In
the commit phase, the coordinator notifies all participants, resources
are released, the transaction is committed, and a commit record
is written to the log. </p>
<A NAME="TI4829"></A><p>Components using two-phase commit must connect to a database
using a PowerBuilder database interface that is XA-compliant. </p>
<A NAME="TI4830"></A><p>An OTS/XA transaction coordinator uses XA resources
instead of connection caches to manage transactions. For more information
about creating and managing XA resources, see the <ACRONYM title = "E A server" >EAServer</ACRONYM> documentation.</p>
<A NAME="TI4831"></A><h4>Creating components that can manage transactions</h4>
<A NAME="TI4832"></A><p>To create an <ABBR title = "e a server" >EAServer</ABBR> component
that can manage transactions, check the OTS Style box in the <ABBR title = "e a server" >EAServer</ABBR> Project wizard or the Project
painter. You can also select OTS Style on the Transaction tab of
the property sheet for the component in <ABBR title = "e a server" >EAServer</ABBR> Manager
or Bean Managed in the Management Console after you have deployed
the component. </p>
<A NAME="TI4833"></A><h4>Initializing the CORBACurrent object</h4>
<A NAME="TI4834"></A><p>Before you can invoke the functions of the CORBACurrent context
service object, you need to create an instance of the object using
the <b>GetContextService</b> function, and then initialize
it using the <b>Init</b> function.</p>
<A NAME="TI4835"></A><p>For transactions managed by a component, call the <b>Init</b> function
with no arguments:<p><PRE> GetContextService("CORBACurrent", myCorbCurr)<br>myCorbCurr.Init()</PRE></p>
<A NAME="TI4836"></A><p>For client-demarcated transactions, you must call the <b>Init</b> function
with an argument: either an instance of the Connection object with
which you have already established a connection, or a URL that identifies
a valid <ABBR title = "e a server" >EAServer</ABBR> host. </p>
<A NAME="TI4837"></A><p>Because the Connection object is more portable, using it is
the preferred technique.<p><PRE> myCorbCurr.Init( myconnect )<br>// OR<br>myCorbCurr.Init( "iiop://localhost:2000")</PRE></p>
<A NAME="TI4838"></A><h4>Beginning and ending transactions</h4>
<A NAME="TI4839"></A><p>You begin a client- or component-demarcated transaction by
calling the <b>BeginTransaction</b> function and end
it by calling <b>CommitTransaction</b> or <b>RollbackTransaction</b>.
Components you instantiate to participate in the transaction must
support transactions.</p>
<A NAME="TI4840"></A><p><p><PRE> // Instance variables:<br>// CORBACurrent corbcurr<br>// Connection myconnect<br> <br><br>int li_rc<br>long ll_rc<br>boolean lb_rc, lb_success<br> <br>ll_rc = myconnect.CreateInstance(mycomponent)<br>li_rc = this.GetContextService("CORBACurrent", &amp;    <br>        corbcurr)<br>IF li_rc &lt;&gt; 1 THEN<br>        // handle error<br>        RETURN<br>END IF<br> <br>li_rc = corbcurr.<i>Init</i>( myconnect )<br>IF li_rc &lt;&gt; 0 THEN<br>        // handle error<br>        RETURN<br>END IF<br> <br>lb_rc = corbcurr.<i>BeginTransaction</i>()<br>// perform some processing on the server and<br>// test for success<br>...<br>IF lb_success THEN<br>        corbcurr.<i>CommitTransaction</i>()<br>ELSE<br>        corbcurr.<i>RollbackTransaction</i>()<br>END IF</PRE></p>
<p><img src="images/note.gif" width=17 height=17 border=0 align="bottom" alt="Note"> <span class=shaded>No nested transactions</span> <A NAME="TI4841"></A>You cannot begin a second transaction until the first transaction
has been committed or rolled back.</p>
<A NAME="TI4842"></A><p>If a component is marked as OTS style, <ABBR title = "e a server" >EAServer</ABBR> does
not start a transaction when the component is instantiated. <ABBR title = "e a server" >EAServer</ABBR> expects the component to
start a transaction by calling the <b>BeginTransaction</b> function
on an instance of a CORBACurrent object. </p>
<p><img src="images/note.gif" width=17 height=17 border=0 align="bottom" alt="Note"> <span class=shaded>Do not call SetComplete</span> <A NAME="TI4843"></A>A component should not begin a transaction and then call <b>SetComplete</b> before committing
or rolling back the transaction. The transaction will be orphaned until
it either times out or is picked up by another transaction.</p>
<A NAME="TI4844"></A><h4>Getting information about the transaction</h4>
<A NAME="TI4845"></A><p>CORBACurrent provides two functions for obtaining information
about the transaction: <b>GetStatus</b> and <b>GetTransactionName</b>. <b>GetStatus</b> returns
an <b>Integer</b> that indicates whether the transaction
is active, has been marked for rollback, is in the prepare phase
or commit phase, or has been committed or rolled back. <b>GetTransactionName</b> returns
a <b>String</b> that identifies the current transaction.
It is intended for use in debugging.</p>
<A NAME="TI4846"></A><h4>Suspending and resuming a transaction</h4>
<A NAME="TI4847"></A><p>A calling thread can suspend a transaction while the thread
performs some non-transactional processing and then resume
it. <b>SuspendTransaction</b> returns a handle to the
transaction that can be passed to the <b>ResumeTransaction</b> function. <b>ResumeTransaction</b> can
be called from a different thread in the same execution context.
In this example, the transaction is reassociated with the same thread:</p>
<A NAME="TI4848"></A><p><p><PRE> long ll_rc<br>unsignedlong ll_handle<br>...<br>ll_rc = corbcurr.BeginTransaction()<br>// do some transactional work<br>ll_handle = corbcurr.<i>SuspendTransaction</i>()<br>// do some non-transactional work<br>corbcurr.<i>ResumeTransaction</i>(ll_handle)<br>// do some more transactional work</PRE></p>
<A NAME="TI4849"></A><h4>Setting a timeout period for transactions</h4>
<A NAME="TI4850"></A><p>A calling thread can specify a timeout period after which
a transaction will be rolled back. This example sets the timeout
period to three minutes (180 seconds):</p>
<A NAME="TI4851"></A><p><p><PRE> integer li_rc<br> <br></PRE><PRE> li_rc = this.GetContextService("CORBACurrent", &amp;<br>        corbcurr)<br>IF li_rc &lt;&gt; 1 THEN<br>        // handle error and return<br>END IF<br>li_rc = corbcurr.Init()<br>IF li_rc &lt;&gt; 1 THEN<br>        // handle error and return<br>END IF<br>corbcurr.<i>SetTimeout</i>(180)<br>corbcurr.BeginTransaction()</PRE></p>

